package org.hilo.boot.app.config;

import java.net.UnknownHostException;

import org.hilo.boot.core.redis.RedisTemplateConfiguration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import io.lettuce.core.RedisClient;

/**
 * <p>默认Redis源配置（覆盖spring默认的spring.boot.autoconfigure.data.redis.RedisAutoConfiguration）</p>
 * 
 * <p>如需其他Redis源{XXX}，新建一个 RedisConfig{XXX} 类继承 AbstractRedisConfig，
 *    参见Demo：{@link RedisConfigFoo2}</p>
 * 
 * @author zollty
 * @since 2018年6月26日
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "hilo.enable-default-redis", havingValue = "true", matchIfMissing = true)
@ConditionalOnClass(RedisClient.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ DefaultLettuceConnectionFactory.class, DefaultJedisConnectionFactory.class })
public class RedisConfig extends RedisTemplateConfiguration {

    public static final String PREFIX = "hilo.multi.redis.";
    public static final String NAMES = "hilo.multi.redis.names";

    public RedisConfig(
            @Qualifier("redisConnectionFactory") RedisConnectionFactory connectionFactory) {
        super(connectionFactory);
    }

    @Primary
    @Bean
    // @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate() throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
        template.setConnectionFactory(connectionFactory);
        return template;
    }

    @Primary
    @Bean
    // @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate() throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(connectionFactory);
        return template;
    }

    @Primary
    /** 对于(Object implements Serializable)，使用JDK对象序列化 */
    @Bean
    RedisTemplate<String, java.io.Serializable> serialRedisTemplate() {
        return initJdkSerialTemplate(java.io.Serializable.class);
    }

    @Primary
    /** 对于Number类型，使用ToString序列化 */
    @Bean
    RedisTemplate<String, Number> numRedisTemplate() {
        return initGenericToStrTemplate(Number.class);
    }

    @Primary
    /** 定义一个ValueOperations，方便日常使用 */
    @Bean
    ValueOperations<String, String> strOperations(StringRedisTemplate redisTemplate) {
        return redisTemplate.opsForValue();
    }

}
